package com.rajesh.messageservice.crack;

import android.content.Context;

import com.rajesh.messageservice.MsgSvc;
import com.rajesh.messageservice.bean.WxDbBean;

import net.sqlcipher.Cursor;
import net.sqlcipher.database.SQLiteDatabase;
import net.sqlcipher.database.SQLiteDatabaseHook;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 微信本地数据库读写工具
 */
public class DatabaseCracker {
    private final String TAG = "DatabaseCracker";
    private SQLiteDatabase database = null;
    private static DatabaseCracker instance = null;

    public static DatabaseCracker createInstance(Context context) throws IOException {
        if(instance == null){
            //check access permission for db
            CommandExecutor.changeWechatFilesPermission();
            String dbPath = WeChatCracker.getUserDataBasePath(true);
            String pragmaKey = WeChatCracker.computePragmaKey(context);
            instance = new DatabaseCracker(dbPath, pragmaKey);
        }
        return instance;
    }

    /**
     * 初始化 sqlcipher 数据库访问对象
     *
     * @param dbPath    数据库路径
     * @param pragmaKey 密钥
     * @author Rajesh
     */
    private DatabaseCracker(String dbPath, String pragmaKey) {
        database = SQLiteDatabase.openDatabase(dbPath, pragmaKey,
                null,
                SQLiteDatabase.OPEN_READONLY | SQLiteDatabase.NO_LOCALIZED_COLLATORS,
                sqLiteDatabaseHook);
    }

    private SQLiteDatabaseHook sqLiteDatabaseHook = new SQLiteDatabaseHook() {
        @Override
        public void preKey(SQLiteDatabase sqLiteDatabase) {
        }

        @Override
        public void postKey(SQLiteDatabase sqLiteDatabase) {
            sqLiteDatabase.rawExecSQL("PRAGMA kdf_iter = 4000;");
            sqLiteDatabase.rawExecSQL("PRAGMA cipher_use_hmac = OFF;");
        }
    };

    /**
     * 查询微信数据库（多条数据）
     *
     * @param c        数据库表结构对应数据载体实体类
     * @param queryStr 数据查询语句
     * @return 查询结果
     */
    public <T extends WxDbBean> List<T> select(Class c, String queryStr) {
        List<T> arrayLst = new ArrayList<>();
        Cursor cursor = null;
        try {
            cursor = database.rawQuery(queryStr, null);
            while (cursor.moveToNext()) {
                T t = (T) c.newInstance();
                t.translate(cursor);
                arrayLst.add(t);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (cursor != null)
                cursor.close();
        }
        return arrayLst;
    }

    /**
     * 查询微信数据库（单条数据）
     *
     * @param c        数据库表结构对应数据载体实体类
     * @param queryStr 数据查询语句
     * @return 查询结果
     */
    public <T extends WxDbBean> T single(Class c, String queryStr) {
        Cursor cursor = null;
        T t = null;
        try {
            cursor = database.rawQuery(queryStr, null);
            if (cursor.moveToNext()) {
                t = (T) c.newInstance();
                t.translate(cursor);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (cursor != null)
                cursor.close();
        }
        return t;
    }

    /**
     * 关闭数据库连接
     */
    @Override
    protected void finalize() throws Throwable {
        if (database != null && database.isOpen())
            database.close();

        super.finalize();
    }
}
